import React, { useRef, useEffect, useState, useCallback } from 'react';
import { cn } from '../../utils/cn';

export interface SphereImageGalleryProps {
  /**
   * 图片URL数组
   */
  images: string[];
  /**
   * 最小展示图片数量
   * 如果传入的图片数量少于这个值，会自动重复图片来达到最小数量
   * @default 12
   */
  minImages?: number;
  /**
   * 球体半径（像素）
   * @default 200
   */
  radius?: number;
  /**
   * 图片尺寸（像素）
   * @default 100
   */
  imageSize?: number;
  /**
   * 旋转速度系数（0-1）
   * 0表示不自动旋转，1表示最快速度
   * @default 0.2
   */
  autoRotateSpeed?: number;
  /**
   * 类名
   */
  className?: string;
}

/**
 * 3D球形图片展示组件
 * 支持鼠标拖拽旋转，图片整齐排列成球形
 */
export const SphereImageGallery: React.FC<SphereImageGalleryProps> = ({
  images,
  minImages = 12,
  radius = 200,
  imageSize = 100,
  autoRotateSpeed = 0.2,
  className = '',
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const sphereRef = useRef<HTMLDivElement>(null);
  const [isDragging, setIsDragging] = useState(false);
  const [rotation, setRotation] = useState({ x: 0, y: 0 });
  const [lastMousePos, setLastMousePos] = useState({ x: 0, y: 0 });
  const autoRotationRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 });

  // 处理图片数量不足的情况
  const processedImages = React.useMemo(() => {
    if (images.length >= minImages) {
      return images;
    }
    
    // 重复图片直到达到最小数量
    const repeatedImages = [];
    while (repeatedImages.length < minImages) {
      repeatedImages.push(...images);
    }
    return repeatedImages.slice(0, minImages);
  }, [images, minImages]);

  // 计算球体上每个图片的位置
  const getImagePositions = useCallback(() => {
    const numImages = processedImages.length;
    const positions = [];
    
    // 使用斐波那契球面分布算法来均匀分布图片
    const goldenRatio = (1 + Math.sqrt(5)) / 2;
    
    for (let i = 0; i < numImages; i++) {
      const theta = 2 * Math.PI * i / goldenRatio;
      const phi = Math.acos(1 - 2 * (i + 0.5) / numImages);
      
      const x = radius * Math.sin(phi) * Math.cos(theta);
      const y = radius * Math.sin(phi) * Math.sin(theta);
      const z = radius * Math.cos(phi);
      
      positions.push({ x, y, z });
    }
    
    return positions;
  }, [processedImages.length, radius]);

  const imagePositions = getImagePositions();

  // 鼠标事件处理
  const handleMouseDown = useCallback((e: React.MouseEvent) => {
    setIsDragging(true);
    setLastMousePos({ x: e.clientX, y: e.clientY });
  }, []);

  const handleMouseMove = useCallback((e: MouseEvent) => {
    if (!isDragging) return;
    
    const deltaX = e.clientX - lastMousePos.x;
    const deltaY = e.clientY - lastMousePos.y;
    
    setRotation(prev => ({
      x: prev.x + deltaY * 0.5,
      y: prev.y + deltaX * 0.5,
    }));
    
    setLastMousePos({ x: e.clientX, y: e.clientY });
  }, [isDragging, lastMousePos]);

  const handleMouseUp = useCallback(() => {
    setIsDragging(false);
  }, []);

  // 自动旋转
  useEffect(() => {
    if (autoRotateSpeed > 0) {
      autoRotationRef.current = {
        x: autoRotateSpeed * 0.1,
        y: autoRotateSpeed * 0.05,
      };
    } else {
      autoRotationRef.current = { x: 0, y: 0 };
    }
  }, [autoRotateSpeed]);

  // 动画循环
  useEffect(() => {
    let animationFrameId: number;
    
    const animate = () => {
      if (!isDragging && autoRotateSpeed > 0) {
        setRotation(prev => ({
          x: prev.x + autoRotationRef.current.x,
          y: prev.y + autoRotationRef.current.y,
        }));
      }
      animationFrameId = requestAnimationFrame(animate);
    };
    
    animationFrameId = requestAnimationFrame(animate);
    
    return () => {
      cancelAnimationFrame(animationFrameId);
    };
  }, [isDragging, autoRotateSpeed]);

  // 事件监听器
  useEffect(() => {
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
    
    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };
  }, [handleMouseMove, handleMouseUp]);

  return (
    <div 
      ref={containerRef}
      className={cn(
        'relative w-full h-96 flex items-center justify-center overflow-hidden cursor-grab',
        isDragging && 'cursor-grabbing',
        className
      )}
      onMouseDown={handleMouseDown}
    >
      <div 
        ref={sphereRef}
        className="relative w-0 h-0"
        style={{
          transform: `rotateX(${rotation.x}deg) rotateY(${rotation.y}deg)`,
          transformStyle: 'preserve-3d',
          transition: isDragging ? 'none' : 'transform 0.1s ease-out',
        }}
      >
        {processedImages.map((imageUrl, index) => {
          const position = imagePositions[index];
          if (!position) return null;
          
          return (
            <div
              key={index}
              className="absolute transform-gpu will-change-transform"
              style={{
                width: `${imageSize}px`,
                height: `${imageSize}px`,
                transform: `translate3d(${position.x}px, ${position.y}px, ${position.z}px)`,
                transformStyle: 'preserve-3d',
              }}
            >
              <img
                src={imageUrl}
                alt={`Gallery image ${index + 1}`}
                className="w-full h-full object-cover rounded-lg shadow-lg border-2 border-white/20 hover:border-white/40 transition-all duration-300 hover:scale-110"
                style={{
                  transform: `rotateY(${-rotation.y}deg) rotateX(${-rotation.x}deg)`,
                }}
                onError={(e) => {
                  // 图片加载失败时的处理
                  const target = e.target as HTMLImageElement;
                  target.style.display = 'none';
                }}
              />
            </div>
          );
        })}
      </div>
    </div>
  );
};

export default SphereImageGallery;